using Avalonia;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Media;

namespace Digitalmes.AvaloniaUI.Behaviors.DragAndDrop;

/// <summary>
/// 可拖动的直线。 
/// </summary>
public class DraggableLine : DraggableControl
{
    private Point _startPoint; // 直线的起点
    private Point _endPoint;   // 直线的终点
    private readonly Canvas _canvas; // 画布

    private bool _isDraggingStart; // 是否正在拖动起点
    private bool _isDraggingEnd;   // 是否正在拖动终点

    /// <summary>
    /// 线条粗细属性。
    /// </summary>
    public static readonly StyledProperty<double> TicknessProperty =
        AvaloniaProperty.Register<DraggableLine, double>(nameof(Tickness), 2.0);

    /// <summary>
    /// 获取或设置线条粗细。
    /// </summary>
    public double Tickness
    {
        get => GetValue(TicknessProperty);
        set => SetValue(TicknessProperty, value);
    }

    public DraggableLine(Point origin, Canvas canvas)
    {
        _startPoint = origin;
        _canvas = canvas;

        // 计算直线末端是否有超出边界
        var canvasRect = canvas.Bounds;
        _endPoint = new Point(Math.Clamp(origin.X + 50, origin.X, canvasRect.Width),
            Math.Clamp(origin.Y + 50, origin.Y, canvasRect.Height));
    }

    /// <summary>
    /// 启用菜单。
    /// </summary>
    public void EnableContextMenu()
    {
        ContextMenu = new ContextMenu();

        // 菜单删除项
        var deleteMenuItem = new MenuItem { Header = "删除" };
        deleteMenuItem.Click += (s, e) =>
        {
            _canvas.Children.Remove(this);
        };

        ContextMenu.Items.Add(deleteMenuItem);
    }

    protected override void OnPointerPressed(PointerPressedEventArgs e)
    {
        base.OnPointerPressed(e);

        if (e.GetCurrentPoint(this).Properties.IsLeftButtonPressed)
        {
            var position = e.GetPosition(this);

            if (IsNearPoint(position, _startPoint))
            {
                _isDraggingStart = true;
            }
            else if (IsNearPoint(position, _endPoint))
            {
                _isDraggingEnd = true;
            }
        }

        e.Handled = true;
    }

    protected override void OnPointerMoved(PointerEventArgs e)
    {
        if (!_isDraggingStart && !_isDraggingEnd)
        {
            return;
        }

        var position = e.GetPosition(_canvas);
        if (!IsValidPosition(position))
        {
            return;
        }

        base.OnPointerMoved(e);

        if (_isDraggingStart)
        {
            _startPoint = position;
        }
        else if (_isDraggingEnd)
        {
            _endPoint = position;
        }

        InvalidateVisual(); // 重绘（标记元素的视觉树为无效）
    }

    protected override void OnPointerReleased(PointerReleasedEventArgs e)
    {
        base.OnPointerReleased(e);

        _isDraggingStart = false;
        _isDraggingEnd = false;

        InvalidateVisual();
    }

    public override void Render(DrawingContext context)
    {
        base.Render(context);

        context.DrawLine(new Pen(Brushes.Red, Tickness), _startPoint, _endPoint);
    }

    protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
    {
        base.OnPropertyChanged(change);

        switch (change.Property.Name)
        {
            case nameof(Tickness):
                InvalidateVisual(); // 重绘（标记元素的视觉树为无效）
                break;
            default:
                break;
        }
    }

    /// <summary>
    /// 判断点是否在目标点附近。
    /// </summary>
    private static bool IsNearPoint(Point p, Point target)
    {
        const double threshold = 10;
        return Math.Abs(p.X - target.X) <= threshold && Math.Abs(p.Y - target.Y) <= threshold;
    }

    /// <summary>
    /// 检查点是否在 Canvas 内。
    /// </summary>
    private bool IsValidPosition(Point point)
    {
        // 检查直线点击的点是否都在 Canvas 内
        var canvasWidth = _canvas.Bounds.Width;
        var canvasHeight = _canvas.Bounds.Height;

        return point.X >= 0
            && point.X <= canvasWidth
            && point.Y >= 0
            && point.Y <= canvasHeight;
    }
}
